package com.tingyuge.thinking.spring.configuration.bean.lifecycle;

import com.tingyuge.thinking.spring.ioc.overview.domain.SuperUser;
import com.tingyuge.thinking.spring.ioc.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;

/**
 * @author xiaodao
 * @version 1.0
 * @date 2021/7/11
 */
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Nullable
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("superUser", beanName) && SuperUser.class.equals(beanClass)) {
            //把配置的 supperUser 替换掉
            return new SuperUser();
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
            //user 对象不运行属性赋值(配置元信息-->普通的pojo)
            User user = (User) bean;
            user.setId(2l);
            user.setName("后置属性替换");
            return false;
        }
        return true;
    }

    //user 是跳过 bean 赋值阶段(填入)
    //supper 也是完全跳过Bean 实例化 ( bean 属性赋值前 填入)
    // userHolder
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) {
            //假设 <property name="number" value="1"/> 这个配置话 ,那么在 PropertyValues 就包含一个 propertyValue(number=1)
            final MutablePropertyValues propertyValues;
            if (pvs instanceof MutablePropertyValues) {
                propertyValues = (MutablePropertyValues) pvs;
            } else {
                propertyValues = new MutablePropertyValues();
            }
            propertyValues.addPropertyValue("number", 1);
            //原始配置: <property name="description" value=" THE userHolder description"/>
            if (propertyValues.contains("description")) {
                //propertyValue 是不可变的
//                    PropertyValue propertyValue = propertyValues.getPropertyValue("propertyValues");
                propertyValues.removePropertyValue("description");
                propertyValues.addPropertyValue("description", "the userHolder is v2");


            }
            return propertyValues;
        }
        return null;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) {
            UserHolder userHolder = (UserHolder)bean;
            // userHolder description = the userHolder is v2
            userHolder.setDescription("the userHolder is v3");
            return userHolder;
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) {
            UserHolder userHolder = (UserHolder)bean;
            // userHolder description = the userHolder is v2
            userHolder.setDescription("the userHolder is v7");
            return userHolder;
        }
        return bean;
    }
}
